package com.canyou.utils;

import java.util.ArrayList;
import java.util.List;

/**
 * 树构建工具类
 *
 * @author fy
 * @date 2018-08-02 17:43
 */
public final class TreeUtils {

    private TreeUtils() {
    }

    /**
     * 两层循环实现建树
     *
     * @param treeNodes 传入的树节点列表
     * @param rootId    根节点id
     * @param <T>       节点
     * @return
     */
    public static <T extends AbstractTreeNode> List<T> build(List<T> treeNodes, Object rootId) {
        List<T> trees = new ArrayList<>();

        for (T treeNode : treeNodes) {
            // 根节点, 放入根List
            if (rootId.equals(treeNode.getParentId())) {
                trees.add(treeNode);
            }
            for (T it : treeNodes) {
                // 判断父id是节点的id时, 放入child
                if (it.getParentId().equals(treeNode.getId())) {
                    treeNode.addChildren(it);
                }
            }
        }
        return trees;
    }

    /**
     * 使用递归方法建树
     *
     * @param treeNodes 节点列表
     * @param rootId    根节点id
     * @param <T>       节点
     * @return
     */
    public static <T extends AbstractTreeNode> List<T> buildByRecursive(List<T> treeNodes, Object rootId) {
        List<T> trees = new ArrayList<>();
        for (T treeNode : treeNodes) {
            if (rootId.equals(treeNode.getParentId())) {
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找某节点的子节点
     *
     * @param treeNode  根节点
     * @param treeNodes 节点集合
     * @param <T>       节点
     * @return
     */
    private static <T extends AbstractTreeNode> T findChildren(T treeNode, List<T> treeNodes) {
        for (T it : treeNodes) {
            if (treeNode.getId().equals(it.getParentId())) {
                treeNode.addChildren(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }

    /**
     * 递归构建 节点parentId为rootId的列表, 非树形结构
     *
     * @param treeNodes 所有节点
     * @param listNodes 构建出的list
     * @param rootId    根节点id
     * @param <T>       节点
     */
    public static <T extends AbstractTreeNode> void buildList(List<T> treeNodes, List<T> listNodes, Object rootId) {
        for (T treeNode : treeNodes) {
            if (rootId.equals(treeNode.getParentId())) {
                listNodes.add(treeNode);
                buildList(treeNodes, listNodes, treeNode.getId());
            }
        }
    }

    /**
     * 递归构建 节点parentId为rootId的列表, 非树形结构
     *
     * @param treeNodes 所有节点
     * @param listNodes 构建出的list
     * @param rootIds   根节点id集合
     * @param <T>       节点
     */
    public static <T extends AbstractTreeNode> void buildListByRootIds(List<T> treeNodes, List<T> listNodes, Object rootIds) {
        if (rootIds instanceof List) {
            for (T treeNode : treeNodes) {
                if (((List) rootIds).contains(treeNode.getParentId())) {
                    listNodes.add(treeNode);
                    buildList(treeNodes, listNodes, treeNode.getId());
                }
            }
        } else {
            buildList(treeNodes, listNodes, rootIds);
        }
    }

    /**
     * 递归构建 节点parentId为rootId的列表, 指定节点level层级, 非树形结构
     *
     * @param treeNodes 所有节点
     * @param listNodes 构建出的list
     * @param rootId    根节点id
     * @param level     要查找的子节点层级
     * @param <T>       节点
     */
    public static <T extends AbstractTreeNode> void buildList(List<T> treeNodes, List<T> listNodes, Object rootId, int level) {
        if (level <= 0) {
            return;
        }
        for (T treeNode : treeNodes) {
            if (rootId.equals(treeNode.getParentId())) {
                listNodes.add(treeNode);
                buildList(treeNodes, listNodes, treeNode.getId(), level - 1);
            }
        }
    }


}
